# 导入标准库/第三方库部分
from django.contrib.auth.models import AnonymousUser
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.generics import (
    GenericAPIView,
    ListCreateAPIView,
    RetrieveUpdateDestroyAPIView
)
from rest_framework.viewsets import ModelViewSet, ViewSet
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from rest_framework.authentication import TokenAuthentication
from rest_framework_simplejwt.tokens import RefreshToken

# 导入应用内模块部分
from app01.models import (
    User,
    Article,
    ArticleTag,
    Tag,
    Comment,
)
from app01.serializers import (
    UserSerializer,
    LoginSerializer,
    ArticleSerializer,
    ArticleTagSerializer,
    TagSerializer,
    CommentSerializer,
)


class UserView(GenericAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    # authentication_classes = [JWTAuthentication]  # 添加Token认证
    # permission_classes = [IsAuthenticated]  # 需要登录才能访问

    def get_permissions(self):
        if self.request.method == 'POST':
            return []
        else:
            return [IsAuthenticated()]

    def get(self, request):
        serializer = UserSerializer(instance=self.get_queryset(), many=True)
        return Response(serializer.data)

    def post(self, request):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors)


class UserDetailView(GenericAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    lookup_field = 'pk'  # 默认情况下使用pk作为查找字段，也可以自定义

    def get(self, request, pk):
        serializer = UserSerializer(instance=self.get_object())
        return Response(serializer.data)

    def put(self, request, pk):
        serializer = self.get_serializer(instance=self.get_object(), data=request.data)
        if serializer.is_valid(raise_exception=True):
            serializer.save()
        return Response(serializer.data)

    def delete(self, request, pk):
        user = self.get_object()
        user.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)  # 删除成功返回空响应，HTTP状态码为204


class LoginAPIView(APIView):
    serializer_class = LoginSerializer
    authentication_classes = []  # 清空Token认证
    permission_classes = []  # 允许无登录访问

    def post(self, request):
        serializer = self.serializer_class(data=request.data, context={'request': request})
        serializer.is_valid(raise_exception=True)

        user = serializer.validated_data['user']

        # 生成并返回JWT Token
        refresh = RefreshToken.for_user(user)
        data = {
            'refresh': str(refresh),
            'access': str(refresh.access_token),
        }

        return Response(data, status=status.HTTP_200_OK)


class ArticleView(APIView):

    def get_permissions(self):
        if self.request.method == 'GET':
            return []
        else:
            return [IsAuthenticated()]

    def get(self, request):
        article_list = Article.objects.all()
        serializer = ArticleSerializer(instance=article_list, many=True)
        return Response(serializer.data)

    def post(self, request):
        serializer = ArticleSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        else:
            return Response(serializer.errors)


class ArticleDetailView(APIView):

    def get_permissions(self):
        if self.request.method == 'GET':
            return []
        else:
            return [IsAuthenticated()]

    def get_authentication_classes(self):
        if self.request.method == 'GET':
            return []
        else:
            return [TokenAuthentication]

    def get(self, request, pk):
        article = Article.objects.get(article_id=pk)
        serializer = ArticleSerializer(instance=article)
        return Response(serializer.data)

    def put(self, request, pk):
        article = Article.objects.get(article_id=pk)
        serializer = ArticleSerializer(instance=article, data=request.data)
        if serializer.is_valid():
            print(serializer.validated_data)
            Article.objects.filter(article_id=pk).update(**serializer.validated_data)
            return Response(serializer.data)
        else:
            Response(serializer.errors)

    def delete(self, request, pk):
        Article.objects.get(article_id=pk).delete()
        return Response()


class ArticleTagView(ViewSet):

    def get_permissions(self):
        if self.request.method == 'GET':
            return []
        else:
            return [IsAuthenticated()]

    def get_article_tag(self, request):
        article_tag_list = ArticleTag.objects.all()
        serializer = ArticleTagSerializer(instance=article_tag_list, many=True)
        return Response(serializer.data)

    def create(self, request):
        serializer = ArticleTagSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        else:
            return Response(serializer.errors)


class ArticleTagDetailView(ViewSet):
    def retrieve(self, request, pk):
        article = ArticleTag.objects.get(id=pk)
        serializer = ArticleTagSerializer(instance=article)
        return Response(serializer.data)

    def update(self, request, pk):
        article = ArticleTag.objects.get(id=pk)
        serializer = ArticleTagSerializer(instance=article, data=request.data)
        if serializer.is_valid():
            print(serializer.validated_data)
            ArticleTag.objects.filter(article_id=pk).update(**serializer.validated_data)
            return Response(serializer.data)
        else:
            Response(serializer.errors)

    def destroy(self, request, pk):
        ArticleTag.objects.get(id=pk).delete()
        return Response()


class TagView(ListCreateAPIView):
    queryset = Tag.objects.all()
    serializer_class = TagSerializer

    def get_permissions(self):
        if self.request.method == 'GET':
            return []
        else:
            return [IsAuthenticated()]


class TagDetailView(RetrieveUpdateDestroyAPIView):
    queryset = Tag.objects.all()
    serializer_class = TagSerializer

    def get_permissions(self):
        if self.request.method == 'GET':
            return []
        else:
            return [IsAuthenticated()]


class CommentView(ModelViewSet):
    queryset = Comment.objects.all()
    serializer_class = CommentSerializer
